package ltd.nullpointer.frontend.service;

import com.google.common.collect.ImmutableMap;
import com.boot2.core.dao.mybatis.MyIbatisBaseDao;
import com.boot2.core.utils.StringUtils;
import lombok.extern.apachecommons.CommonsLog;
import ltd.nullpointer.frontend.constant.DeviceConstant;
import ltd.nullpointer.frontend.model.dto.up.FormulaDto;
import ltd.nullpointer.frontend.model.entity.NpAttributeKv;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.ibatis.session.SqlSession;
import org.springframework.stereotype.Service;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Author wangzheng
 * Created on 2017/12/13.
 * Description
 */
@Service
@CommonsLog
public class NpAtrributeKvService extends MyIbatisBaseDao<NpAttributeKv> {

    /**
     * 按传感器编号查询传感器设备与token映射列表
     *
     * @param sensorNo
     * @return
     */
    private String selectDeviceTokenBySensoNo(String sensorNo) {
        List<Map<String, String>> selectDeviceTokenMapList = getSqlSession().selectList("selectDeviceToken", ImmutableMap.of("sensorNo", sensorNo));
        if (CollectionUtils.isNotEmpty(selectDeviceTokenMapList)) {
            Map<String, String> deviceTokenMap = selectDeviceTokenMapList.get(0);
            ImmutableMap<String, String> immutableMap = ImmutableMap.of(deviceTokenMap.get("sensorNo"), deviceTokenMap.get("token"));
            DeviceConstant.deviceTokenMap.putAll(immutableMap);
            return deviceTokenMap.get("token");
        }
        return null;
    }


    /**
     * 查询所有的设备与token映射列表,此确保尽量只在启动初始化时调用
     *
     * @return
     */
    public void initAllDeviceTokenList() {
        List<Map<String, String>> selectDeviceTokenMapList = getSqlSession().selectList("selectDeviceToken", null);
        if (CollectionUtils.isNotEmpty(selectDeviceTokenMapList)) {
            for (Map<String, String> deviceTokenMap : selectDeviceTokenMapList) {
                ImmutableMap<String, String> immutableMap = ImmutableMap.of(deviceTokenMap.get("sensor_no"), deviceTokenMap.get("token"));
                DeviceConstant.deviceTokenMap.putAll(immutableMap);
            }
        }
    }

//    /**
//     * 查询所有模块编号与传感器编号的关联列表 此确保尽量只在启动初始化时调用
//     * @return
//     */
//    public Map<String, String> selectSensorNoMap() {
//        List<Map<String, String>> selectDeviceTokenMapList = getSqlSession().selectList("selectSensorNoListByStationNo", null);
//        if (CollectionUtils.isNotEmpty(selectDeviceTokenMapList)) {
//            for (Map<String, String> stationNoSensorNoMap : selectDeviceTokenMapList) {
//                ImmutableMap<String, String> immutableMap = ImmutableMap.of(stationNoSensorNoMap.get("stationNo"), stationNoSensorNoMap.get("sensorNo"));
//                DeviceConstant.stationNoSensorNoMap.putAll(immutableMap);
//            }
//        }
//        return DeviceConstant.stationNoSensorNoMap;
//
//    }


    /**
     * 通过模块编号查询传感器编号列表
     *
     * @param stationNo
     * @return
     */
    public List<String> selectSensorNoListByStationNo(String stationNo) {
        List<String> stationNoSensorNoList = null;
        List<Map<String, String>> sensorNoMapList = selectSensorNoAndStationNoList(stationNo);
        if (CollectionUtils.isNotEmpty(sensorNoMapList)) {
            for (Map<String, String> stationNoSensorNoMap : sensorNoMapList) {
                String stationNo1 = stationNoSensorNoMap.get("station_no");
                String sensorNo = stationNoSensorNoMap.get("sensor_no");
                //一个模块编号对应的传感器列表
                stationNoSensorNoList = DeviceConstant.stationNoSensorNoListMap.getOrDefault(stationNo1, new ArrayList<>());
                stationNoSensorNoList.add(sensorNo);
                DeviceConstant.stationNoSensorNoListMap.put(stationNo1, stationNoSensorNoList);
            }
        }
        return StringUtils.isNotEmpty(stationNo) ? stationNoSensorNoList : null;
    }

    public List<Map<String, String>> selectSensorNoAndStationNoList(String stationNo) {
        return getSqlSession().selectList("selectSensorNoListByStationNo", new HashMap<String, String>(1) {{
            put("stationNo", stationNo);
        }});
    }

    /**
     * 查询所有的模块编号与传感器编号映射列表，一对多
     */
    public void initAllStationNoSensorNoList() {
        selectSensorNoListByStationNo(null);
    }

    /**
     * 通过传感器编号得到访问token
     *
     * @param sensorNo
     * @return
     */
    public String getTokenBySensorNo(String sensorNo) {
        String token = DeviceConstant.deviceTokenMap.get(sensorNo);
        if (StringUtils.isNotEmpty(token)) {
            return token;
        } else {
            token = selectDeviceTokenBySensoNo(sensorNo);
            return token;
        }
    }

    /**
     * 通过模块编号得到传感器列表
     *
     * @param stationNo
     * @return
     */
    public List<String> getSensorNoListByStationNo(String stationNo) {
        List<String> sensorNoList = DeviceConstant.stationNoSensorNoListMap.get(stationNo);
        if (CollectionUtils.isNotEmpty(sensorNoList)) {
            return sensorNoList;
        } else {
            sensorNoList = selectSensorNoListByStationNo(stationNo);
            return sensorNoList;
        }
    }

    /**
     * 获取指定设备所有的属性值,临时用遍历
     *
     * @param sensorNo
     * @return
     */
    public Map<String, Double> selectAllAttributeKv(String sensorNo) {
        Map<String, Double> formulaMap = new HashMap<>();
        List<Map<String, Object>> allAttributeKvList = getSqlSession().selectList("selectAllAttributeKv", sensorNo);
        if (CollectionUtils.isNotEmpty(allAttributeKvList)) {
            for (Map<String, Object> map : allAttributeKvList) {
                String attributeKey = (String) map.get("attributekey");
                Double doubleValue = (Double) map.get("doublevalue");
                doubleValue = doubleValue == null ? 0 : doubleValue;
                formulaMap.put(attributeKey, doubleValue);
            }
        }
        return formulaMap;
    }

    /**
     * 设置动态属性值
     *
     * @param map
     */
    public void updateSetKv(Map<String, Object> map) {
        getSqlSession().update("setKv", map);
    }

    public void updateSetFormula(FormulaDto formulaDto) {
        try {
            Map<String, String> map = BeanUtils.describe(formulaDto);
            map.remove("sensorNo");
            map.remove("class");
            Map<String, Object> map2 = new HashMap<>();
            map.forEach((k, v) -> {
                if (StringUtils.isNotEmpty(v)) {
//                    k = StringUtils.humpToLine(k);
                    map2.put(k, v);
                }
            });
            Map<String, Object> paramMap = new HashMap<>();
            paramMap.put("paramMap", map);
            paramMap.put("sensorNo", formulaDto.getSensorNo());
            updateSetKv(paramMap);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }


    }


    /**
     * 动态创建属性
     */
    public int genColumns(String sensorNo) {
        int count = 0;
        Map<String, String> paramMap = new HashMap<>();
        paramMap.put("attribute_key", "dev_num");
        paramMap.put("str_v", sensorNo);
        SqlSession sqlSession = getSqlSession();
        List<Map<String, String>> deviceEntityIdList = sqlSession.selectList("selectAllDevice", paramMap);
        System.out.println("deviceEntityIdList = " + deviceEntityIdList);

        Map<String, Object> dataMap = new HashMap<>();
//        dataMap.put("deviceEntityIdList", deviceEntityIdList);

        Map<String, Object> columnsMap = new HashMap<>();
        //初始值
        columnsMap.put("initial_value", 0);
        //水平高度
        columnsMap.put("height", 0);
        //安装深度
        columnsMap.put("depth", 0);
        //比例系数
        columnsMap.put("ratio", 1);
        //计数控制
        columnsMap.put("control_flag", 0);

        dataMap.put("columnsMap", columnsMap);
        if (CollectionUtils.isNotEmpty(deviceEntityIdList)) {
            for (Map<String, String> map : deviceEntityIdList) {
                dataMap.put("entityId", map.get("entity_id"));
                try {
                    sqlSession.insert("insertGenColumns", dataMap);
                    count++;
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }
        return count;
    }
}
